// AudioPlug test with Infrared receiver using the InfraredPlug class (interrupt version)
// 2011-02-05 <info@theater4all.nl> http://opensource.org/licenses/mit-license.php

#include <Ports.h>
#include <PortsLCD.h>
#include <RF12.h> // needed to avoid a linker error :(
#include <AudioPlug.h>

#define INCR 5

AudioPlug Plug(PORTHIGH);
InfraredPlug ir (2);
PortI2C myI2C (1);
LiquidCrystalI2C lcd (myI2C);

byte VolIncr;
byte VolDecr;
byte MuteCode;

byte count;
const byte* data;
byte lastValue;

byte volValue;

bool ValidCode;
bool muteActive;

ISR(PCINT1_vect) {
  ir.poll();
}



void setup () {
  //Serial.begin(57600);
  //Serial.println("\n[IR audioPlug]");

  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  lcd.backlight();

  // Print a message to the LCD.
  lcd.print("AudioPlug Test");
  delay(2000);

  // init audioPlug
  Plug.addBoard(TWOCHANNELS);
  Plug.setVolume(0, 0);
  Plug.setVolume(1, 0);
  Plug.sendVolumeData(); 

  // enable pin change interrupts on PC1
  PCMSK1 = bit(1);
  PCICR |= bit(PCIE1);

  // learn IR
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Press Vol incr ");
  VolIncr = getIRValue();

  lcd.setCursor(0, 0);
  lcd.print("Press Vol decr ");
  VolDecr = getIRValue();

  lcd.setCursor(0, 0);
  lcd.print("Press Mute     ");
  MuteCode = getIRValue();  

  lcd.setCursor(0, 0);
  lcd.print("Done.          ");
  delay(2000);

  // init
  ValidCode = false;
  muteActive = false;

  // LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Volume:");
  lcd.setCursor(9, 0);
  lcd.print("-95dB");
  updateVolume(0);
}


byte getIRValue(void)
{
  while (1) {
    count = ir.done();
    if (count > 0) {
      data = ir.buffer();
      if (ir.decoder(count) ==  InfraredPlug::NEC) {
        lcd.setCursor(0, 1);
        lcd.print(data[3], HEX);
        return data[3];
      }
    }
  }
}

void updateVolume(byte val)
{
  int f = 31 - ((255 - val) >> 1);

  lcd.setCursor(9, 0);
  if (f >= 0) {
    lcd.print (" ");
    if (f < 10) lcd.print (" ");
    lcd.print(f,DEC);
  }
  else if (f > -10) {
    lcd.print ("- ");
    lcd.print(-f,DEC);
  }
  else {
    lcd.print(f,DEC);
  }
}

byte incrVol (int val)
{
  val += INCR;
  if (val > 255) val = 255;
  return val;
}

byte decrVol (int val)
{
  val -= INCR;
  if (val < 0) val = 0;
  return val;
}

void loop () {
  count = ir.done();
  if (count > 0) {
    data = ir.buffer();

    // check code
    if (ir.decoder(count) ==  InfraredPlug::NEC) {
      lastValue = data[3];
      ValidCode = true;
    }
    else if (ir.decoder(count) == InfraredPlug::NEC_REP) {
      // do not repeat Mute-toggle
      if (lastValue != MuteCode)
        ValidCode = true;
    }

    // got something ?
    if (ValidCode) {
      ValidCode = false;
      if (lastValue == MuteCode) {
        muteActive = !muteActive;
        lcd.setCursor(0, 1);
        lcd.print(muteActive ? "Mute On" : "Mute Off");
        Plug.setMute(muteActive ? MUTEON : MUTEOFF);
      }
      else if (lastValue == VolIncr) {
        volValue = incrVol(Plug.getVolume(0));
        Plug.setVolume(0, volValue);
        Plug.setVolume(1, volValue);
        updateVolume(volValue);
        Plug.sendVolumeData();
      }
      else if (lastValue == VolDecr) {
        volValue = decrVol(Plug.getVolume(0));
        Plug.setVolume(0, volValue);
        Plug.setVolume(1, volValue);
        updateVolume(volValue);
        Plug.sendVolumeData();      
      }
    }
  }
}










